﻿using System.Collections.Generic;
using Godot.core.os;
using Godot.core;

namespace Godot.core.io
{
    public class PackSourcePCK : PackSource
    {
        public override bool try_open_pack(string p_path)
        {
            Error valid = Error.FAILED;
            FileAccess f = FileAccess.open(p_path, FileAccess.ModeFlags.READ, ref valid);
	        if (null == f)
		        return false;

	        uint magic = f.get_32();

	        if (magic != 0x43504447)
            {
		        //maybe at the end.... self contained exe
		        f.seek_end();
		        f.seek(f.get_pos() - 4);
		        magic = f.get_32();
		        if (magic != 0x43504447) 
                {
			        //memdelete(f);
			        return false;
		        }

		        f.seek(f.get_pos() - 12);


		        ulong ds = f.get_64();
		        f.seek( f.get_pos() - (uint)ds - 8 );

		        magic = f.get_32();
		        if (magic != 0x43504447) 
                {
			        //memdelete(f);
			        return false;
		        }

	        }

	        uint version = f.get_32();
	        uint ver_major = f.get_32();
	        uint ver_minor = f.get_32();
	        uint ver_rev = f.get_32();

	        //ERR_EXPLAIN("Pack version newer than supported by engine: "+itos(version));
	        if( version > Misc.Version.PACK_VERSION) return false;

	        //ERR_EXPLAIN("Pack created with a newer version of the engine: "+itos(ver_major)+"."+itos(ver_minor)+"."+itos(ver_rev));
	        
            if( ver_major > Misc.Version.VERSION_MAJOR || (ver_major == Misc.Version.VERSION_MAJOR && ver_minor > Misc.Version.VERSION_MINOR))
                return false ;

	        for(int i = 0; i < 16; i++) 
            {
		        //reserved
		        f.get_32();
	        }

	        uint file_count = f.get_32();

	        for(int i = 0; i < file_count; i++) 
            {
		        uint sl = f.get_32();
                byte[] cs = new byte[sl];
		        f.get_buffer(cs, (int)sl);
                
                string path = System.Text.Encoding.UTF8.GetString(cs);		     

		        ulong ofs = f.get_64();
		        ulong size = f.get_64();
		        byte[] md5 = new byte[16];
		        f.get_buffer(md5, 16);
		        PackedData.singleton.add_path(p_path, path, ofs, size, md5, this);
	        };

	        return true;
        }

        public override FileAccess get_file(string p_path, ref PackedData.PackedFile p_file)
        {
            return new FileAccessPack(p_path, p_file);
        }
    }
}
